/**
 *
 */
package com.treasure.service.wechat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.treasure.service.commons.lang.util.PicUtil;
import com.treasure.service.commons.lang.util.StringUtil;
import com.treasure.service.commonutil.DrawingUtils;
import com.treasure.service.constant.GlobalConstant;
import com.treasure.service.domain.AccessToken;
import com.treasure.service.dto.wechat.*;
import com.treasure.service.enums.RedisKeys;
import com.treasure.service.third.utils.RestClient;
import com.treasure.service.third.utils.TokenConfig;
import com.treasure.service.third.utils.UserToken;
import com.treasure.service.user.service.UserService;
import com.treasure.service.wechat.common.WxUser;
import com.treasure.service.wechat.service.WechatService;
import com.treasure.service.wechat.utils.WechatMessageUtil;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
* @ClassName: WechatServiceImpl
* @Description: TODO(公众号交互)
* @author <a href="mailto:125671254@qq.com">Pan Xinwen</a>panxinwen
* @date 2018年4月22日 下午3:42:35
*
 */
@Service
public class WechatServiceImpl implements WechatService {

	private Logger log = LoggerFactory.getLogger(WechatServiceImpl.class);
	@Autowired
	private RestClient restClient;
	private static ExecutorService executor = Executors.newFixedThreadPool(2);
	@Autowired
	private UserService userService;

	@Value("${treasure.wx.token}")
	private String treasureWxToken;

	@Value("${treasure.wx.user.access.token}")
	private String treasureWxUserAccessToken;

	@Value("${treasure.service.base.url}")
	private String treasureServiceBaseUrl;

    @Value("${treasure.wx.token.url}")
    private String wxTokenUrl;

    @Value("${treasure.wx.ticket.url}")
    private String wxTicketUrl;

    @Value("${treasure.wx.snsapi.base}")
    private String wxSnsapiBase;

    @Value("${treasure.wx.appId}")
    private String appId;

    @Value("${treasure.mch.id}")
    private String mch_id;

	@Autowired
	private RedisTemplate<String,String> redisTemplate;

    final static  String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
	/* (non-Javadoc)
	 * @see com.shop.service.api.online.WxUtilService#getAccess_token(javax.servlet.http.HttpServletRequest)
	 */
	@Override
	public AccessToken getAccess_token() {
		AccessToken accessToken = JSON.parseObject((String) redisTemplate.opsForHash().get(RedisKeys.ACCESS_TOKEN.build(""), "access_token"),AccessToken.class);
//		Object s = redisTemplate.opsForHash().get("WEB:CACHE:TREASURE:DATA:ACCESS_TOKEN", "access_token");
//		AccessToken accessToken =new AccessToken();
////		accessToken.setAccessToken(s.toString());
//		accessToken.setAccessToken("12313123");
		return accessToken;

	}
	@Override
	public void updateAccess_token() {
		log.info("获取Access_token开始，url========"+wxTokenUrl);
		String result = restClient.get(wxTokenUrl, new HashMap<String,Object>(), String.class);
		log.info("微信服务器获取Access_token:"+result);
		JSONObject obj = JSONObject.parseObject(result);
		String access_token = obj.getString("access_token");
		String ticket = restClient.get(wxTicketUrl+access_token, new HashMap<String,Object>(), String.class);
		obj = JSON.parseObject(ticket);
		String jsapi_ticket = obj.getString("ticket");

		AccessToken wt = new AccessToken();
		wt.setId(Long.parseLong("10000"));
		wt.setAccessToken(access_token);
		wt.setJsapiTicket(jsapi_ticket);

		redisTemplate.opsForHash().put(RedisKeys.ACCESS_TOKEN.build(""), "access_token", JSON.toJSONString(wt));


	}
	@Override
	public void snsapibase(String redirect_uri,String redirect_code,HttpServletResponse response) {
		String baseUrl = wxSnsapiBase;

		try {
//			redisTemplate.opsForHash().put(RedisKeys.REDIRECT_LIST.build(":REDIRECT_LIST"), redirect_code, redirect_uri);
			String url = URLEncoder.encode(treasureServiceBaseUrl+"/redirect", "UTF-8");
			baseUrl=baseUrl+"&redirect_uri="+url+"&response_type=code&scope=snsapi_userinfo&state="+redirect_code+"#wechat_redirect";
			log.info("用户同意授权，获取code，url========"+baseUrl);
//			String result = restClient.get(baseUrl,new HashMap<>(),String.class);
			try {
				response.sendRedirect(baseUrl);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
//			log.info("用户同意授权返回========"+result);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

	}

	@Override
	public WxUser redirect(String code) {

//		String code = request.getParameter("code");
		String baseUrl = treasureWxUserAccessToken+"&code="+code+"&grant_type=authorization_code";
		log.info("获取用户access_token，url========"+baseUrl);
		Map<String,Object> map = new HashMap<String,Object>();
		String string = restClient.get(baseUrl,map,String.class);
//		log.info("获取用户access_toke返回========"+string);
		WxUser result = JSONObject.parseObject(string,WxUser.class);
//		WxUser result = restClient.get(baseUrl,map,WxUser.class);
		log.info("获取用户access_toke返回========"+JSON.toJSONString(result));
		return result;
//		return null;

	}

	@Override
	public String wxListener(String signature,  String timestamp,
             String nonce,  String echostr) throws NoSuchAlgorithmException {

		// 将token、timestamp、nonce三个参数进行字典序排序
		String[] params = new String[] {treasureWxToken, timestamp, nonce };
		Arrays.sort(params);
		// 将三个参数字符串拼接成一个字符串进行sha1加密
		String clearText = params[0] + params[1] + params[2];
		String algorithm = "SHA-1";
		String sign = new String(Hex.encodeHex(MessageDigest.getInstance(algorithm).digest((clearText).getBytes()), true));
		// 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
		log.info("signature========" + signature);
		log.info("sign========" + sign);

		if (signature.equals(sign)) {

			log.info("---------------微信校验成功-------------");
			return echostr;
		}

		return "";

	}

//	@Override
//	public String processRequest(HttpServletRequest request) {
//		return null;
//	}
	@Override
	public String processRequest(HttpServletRequest request) {
		 Map<String, String> map = WechatMessageUtil.xmlToMap(request);
	        log.info("接收到微信推送消息："+JSON.toJSONString(map));
	        // 发送方帐号（一个OpenID）
	        String fromUserName = map.get("FromUserName");
	        // 开发者微信号
	        String toUserName = map.get("ToUserName");
	        // 消息类型
	        String msgType = map.get("MsgType");
	        // 默认回复一个"success"
	        String responseMessage = "success";

	        String Event = map.get("Event");
	        String EventKey =  map.get("EventKey");
	        //建立用户绑定关系
	        if(!StringUtil.isEmpty(Event) && Event.equals("subscribe")){
                TextMessage textMessage = new TextMessage();
                textMessage.setMsgType(WechatMessageUtil.MESSAGE_TEXT);
                textMessage.setToUserName(fromUserName);
                textMessage.setFromUserName(toUserName);
                textMessage.setCreateTime(System.currentTimeMillis());

                if (StringUtil.isNotEmpty(EventKey)){

					userService.bindingRelation(fromUserName,EventKey);

                }

                try {
//                    textMessage.setContent(new String(("淘讯团队欢迎你，很高兴你开启了淘讯周边生活，我们提供基于位置的即时生活资讯，有你的到来会更加精彩☺。\n" +
//                        "想看看周边在发生什么，想找优质的活动信息？请戳“玩转周边”\uD83D\uDC47" +
//                        "\n想分享生活资讯给更多的人，或许会得到很多人的赞赏，请戳“有赏发布”\uD83D\uDC47" +
//                        "\n想知道自己在淘讯做过什么，是不是得到别人的赞赏，请戳“淘讯吧”\uD83D\uDC47" +
//                        "\n期待你能在淘讯获得愉快的生活体验。").getBytes(),"iso8859-1"));
                    textMessage.setContent(new String(("欢迎关注最专业的社交金融平台——生财有道！\n" +
							"\n" +
							"——————————————————\n" +
							"\n" +
							"最广泛的资源——合作16家银行\n" +
							"\n" +
							"最快捷的通道——核卡300万张\n" +
							"\n" +
							"最赚钱的平台——发放奖金3亿元\n" +
							"\n" +
							"上线至今，已有50万创业者加入平台推广业务，累计服务过100万用户\n" +
							"\n" +
							"——————————————————\n" +
							"【花样权益，秒变卡神】\n" +
							"<a href='http://treasure.jingyugg.com/dist/index.html'>申请办理信用卡>>></a>\n" +
							"【超低投入，超高回报】\n" +
							"<a href='http://treasure.jingyugg.com/dist/index.html'>申请成为会员>>></a>").getBytes(),"iso8859-1"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                responseMessage = WechatMessageUtil.textMessageToXml(textMessage);

                // 创建图文消息
//                NewsMessage newsMessage = new NewsMessage();
//                newsMessage.setToUserName(fromUserName);
//                newsMessage.setFromUserName(toUserName);
//                newsMessage.setCreateTime(new Date().getTime());
//                newsMessage.setMsgType(WechatMessageUtil.MESSAGE_NEWS);
//
//                List<ArticleMessage> articleList = new ArrayList<>();
//
//                ArticleMessage article = new ArticleMessage();
//                try {
//                    article.setTitle(new String("淘淘等你很久了".getBytes(),"iso8859-1"));
//                    article.setDescription(new String("想知道周围有哪些好玩的？猛戳这里！".getBytes(),"iso8859-1"));
//                } catch (UnsupportedEncodingException e) {
//                    e.printStackTrace();
//                }
//                article.setPicUrl("http://treasure.jingyugg.com/static/timg.jpg");
//                article.setUrl("http://treasure.jingyugg.com/m/home.html");
//                articleList.add(article);
//                // 设置图文消息个数
//                newsMessage.setArticleCount(articleList.size());
//                // 设置图文消息包含的图文集合
//                newsMessage.setArticles(articleList);
//                XStream xstream = new XStream();
//                xstream.alias("xml", newsMessage.getClass());
//                xstream.alias("item", new ArticleMessage().getClass());
//                responseMessage =  xstream.toXML(newsMessage);



                log.info(responseMessage);
//                return xstream.toXML(newsMessage);
//                return getBlogMessage(toUserName,fromUserName,System.currentTimeMillis());
                //                responseMessage = WechatMessageUtil.textMessageToXml();
            }

	        // 对消息进行处理
	        if (WechatMessageUtil.MESSAGE_TEXT.equals(msgType)) {// 文本消息
	            TextMessage textMessage = new TextMessage();
                textMessage.setMsgType(WechatMessageUtil.MESSAGE_TEXT);
                textMessage.setToUserName(fromUserName);
                textMessage.setFromUserName(toUserName);
                textMessage.setCreateTime(System.currentTimeMillis());
                try {
                    textMessage.setContent(new String("我已经受到你发来的消息了".getBytes(),"UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                responseMessage = WechatMessageUtil.textMessageToXml(textMessage);
	        }
	        log.info(responseMessage);
	        return responseMessage;
	}

	private String getBlogMessage(String custermName, String serverName, Long createTime) {
        NewsMessage outputMsg = new NewsMessage();
        outputMsg.setFromUserName(serverName);
        outputMsg.setToUserName(custermName);
        outputMsg.setCreateTime(createTime);
        outputMsg.setMsgType(WechatMessageUtil.MESSAGE_NEWS);

        List<ArticleMessage> articles = new ArrayList<>();

        ArticleMessage item1 = new ArticleMessage();
        item1.setTitle("淘淘等你很久了");
        item1.setDescription("想知道周围有哪些好玩的？猛戳这里！");
        item1.setPicUrl("http://treasure.jingyugg.com/static/timg.jpg");
        item1.setUrl("http://treasure.jingyugg.com/m/home.html");
        articles.add(item1);

        outputMsg.setArticles(articles);
        outputMsg.setArticleCount(articles.size());

        XStream xstream = new XStream();
        xstream.alias("xml", outputMsg.getClass());
        xstream.alias("item", new ArticleMessage().getClass());

        return  xstream.toXML(outputMsg);
    }

	@Override
	public WxUser wxUserInfo(String openid,String access_token) throws UnsupportedEncodingException {

		log.info("获取微信用户基本信息传入参数：openid{},access_token{}",openid,access_token);

		String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token.toString()+"&openid="+openid+"&lang=zh_CN";
		log.info("获取微信用户基本信息url：url",url);
		Map<String,Object> map = new HashMap<String,Object>();

		String result = restClient.get(url+"",map,String.class);
		log.info("获取微信用户基本信息返回：result",result);
		String json = new String(result.getBytes("ISO-8859-1"), "UTF-8");
		return JSONObject.parseObject(json,WxUser.class);
	}

	//生成分享图片
	@Override
	public String createShareImg(Integer type,String selfInviteCode){
		String ticket=redisTemplate.opsForValue().get(RedisKeys.QRCODE.build("TICKET",selfInviteCode));
		if (StringUtil.isNotEmpty(ticket)){
			return "";
		}

		BufferedImage bufferedImage =getQRCode(selfInviteCode);

		if (type == 1){
			try {
				DrawingUtils.getInviteCardImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
			} catch (Exception e) {
				e.printStackTrace();
			}
			executor.execute(()->{
				try {
					DrawingUtils.getInviteVipImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					DrawingUtils.getInviteLoansImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}else if (type == 2){
			try {
				DrawingUtils.getInviteVipImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,null,selfInviteCode);
			} catch (Exception e) {
				e.printStackTrace();
			}
			executor.execute(()->{
				try {
					DrawingUtils.getInviteCardImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					DrawingUtils.getInviteLoansImg("http://mobile.jingyugg.com/dist/index.html#/landing?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}else {
			try {
				DrawingUtils.getInviteLoansImg("https://www.baidu.com?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
			} catch (Exception e) {
				e.printStackTrace();
			}
			executor.execute(()->{
				try {
					DrawingUtils.getInviteCardImg("https://www.baidu.com?inviteCode="+selfInviteCode,bufferedImage,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					DrawingUtils.getInviteVipImg("https://www.baidu.com?inviteCode="+selfInviteCode,null,selfInviteCode);
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}

		return "";

	}

//	// Todo 生成公众号二维码
//	private BufferedImage getQRCode(String selfInviteCode) {
//
//		String ticket=redisTemplate.opsForValue().get(RedisKeys.QRCODE.build("TICKET",selfInviteCode));//设置邀请海报过期时间
//
//		log.info("缓存中二维码获取ticket："+ticket);
//
//
//		if (StringUtil.isEmpty(ticket)){
//
//			QRTicket qrTicket = new QRTicket();
//			qrTicket.setExpire_seconds(2592000);
//			Scene scene = new Scene();
//			scene.setScene_id(Long.parseLong(selfInviteCode));
//			ActionInfo actionInfo = new ActionInfo();
//			actionInfo.setScene(scene);
//			qrTicket.setAction_info(actionInfo);
//
//			AccessToken accessToken = JSON.parseObject((String) redisTemplate.opsForHash().get(RedisKeys.ACCESS_TOKEN.build(""), "access_token"),AccessToken.class);
//
//			String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+accessToken.getAccessToken();
//			String is = restClient.post(url,qrTicket,String.class);
//			JSONObject jsonObject = JSON.parseObject(is);
//
//			log.info("获取邀请二维码第一步生成ticket：{}",jsonObject);
//			ticket = jsonObject.getString("ticket");
//			redisTemplate.opsForHash().put(RedisKeys.QRCODE.build("TICKET"),selfInviteCode,ticket);
//			redisTemplate.expire(RedisKeys.QRCODE.build("TICKET"), 2592000, TimeUnit.SECONDS); //设置超时时间10秒 第三个参数控制
//			return getRQcode(ticket);
//		}
//
//		return null;
//	}
//	public BufferedImage getRQcode(String ticket)
//	{
//		try
//		{
//			String requestUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+URLEncoder.encode(ticket, GlobalConstant.ENCODING_UTF8);
//			URL url = new URL(requestUrl);
//			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//			conn.setDoInput(true);
//			conn.setRequestMethod("GET");
//
//			// 将微信服务器返回的输入流写入文件
//			BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
//			BufferedImage bufferedImage = ImageIO.read(bis);
//			log.info("根据ticket换取二维码成功");
//			return bufferedImage;
//		} catch (Exception e)
//		{
//			log.error("根据ticket换取二维码失败", e);
//		}
//
//		return null;
//
//	}

	public BufferedImage getQRCode(String selfInviteCode) {

		redisTemplate.opsForValue().get(RedisKeys.QRCODE.build("TICKET",selfInviteCode));

		String filePath = "/data/static/img/RQcode/" + selfInviteCode + ".jpg";

		File file=new File(filePath);
		if(file.exists()&&file.isFile())file.delete();

		QRTicket qrTicket = new QRTicket();
		qrTicket.setExpire_seconds(2592000);
		Scene scene = new Scene();
		scene.setScene_id(Long.parseLong(selfInviteCode));
		ActionInfo actionInfo = new ActionInfo();
		actionInfo.setScene(scene);
		qrTicket.setAction_info(actionInfo);



		String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+getAccess_token().getAccessToken();
		String is = restClient.post(url,qrTicket,String.class);
		JSONObject jsonObject = JSON.parseObject(is);

		log.info("获取邀请二维码第一步生成ticket：{}",jsonObject);
		String ticket = jsonObject.getString("ticket");
		redisTemplate.opsForValue().set(RedisKeys.QRCODE.build("TICKET",selfInviteCode), "100",6000*10,TimeUnit.SECONDS);//设置邀请海报过期时间
		try {
			return  ImageIO.read(new FileInputStream(getRQcode(ticket,selfInviteCode)));
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	public  String getRQcode(String ticket,String selfInviteCode)
	{
		String filePath = "/data/static/img/RQcode/" + selfInviteCode + ".jpg";
		try
		{
			String requestUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+URLEncoder.encode(ticket, GlobalConstant.ENCODING_UTF8);
			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setDoInput(true);
			conn.setRequestMethod("GET");

			// 将微信服务器返回的输入流写入文件
			BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
			FileOutputStream fos = new FileOutputStream(new File(filePath));

			byte[] buf = new byte[8096];
			int size = 0;
			while ((size = bis.read(buf)) != -1)
				fos.write(buf, 0, size);
			fos.close();
			bis.close();

			conn.disconnect();
			//缩放
			PicUtil.zoomImage(filePath,"/data/static/img/RQcode/" + selfInviteCode + "s.jpg",124,124);
			File file=new File(filePath);
			if(file.exists()&&file.isFile())file.delete();
			filePath="/data/static/img/RQcode/" + selfInviteCode + "s.jpg";

			log.info("根据ticket换取二维码成功");
		} catch (Exception e)
		{
			filePath = null;
			log.error("根据ticket换取二维码失败", e);
		}

		return filePath;

	}

}
